Skip to content

fix(ai-react): update messagesRef synchronously during render#373

Open
DiegoGBrisa wants to merge 3 commits intoTanStack:mainfrom
DiegoGBrisa:fix/use-chat-messages-ref-staleness
Open

fix(ai-react): update messagesRef synchronously during render#373
DiegoGBrisa wants to merge 3 commits intoTanStack:mainfrom
DiegoGBrisa:fix/use-chat-messages-ref-staleness

Conversation

@DiegoGBrisa
Copy link
Contributor

@DiegoGBrisa DiegoGBrisa commented Mar 13, 2026

Summary

messagesRef in useChat is updated via useEffect (async), but useMemo reads it during render (sync) to pass initialMessages when creating a new ChatClient. When setMessages and a clientId change are batched into a single React 18 render, the ref is stale — the new client is created with empty messages, losing the conversation history.

The fix replaces the useEffect ref update with a synchronous render-time assignment so messagesRef is always current before useMemo runs.

Test plan

  • Commit 1 adds a failing test that batches setMessages + id change, then sends a message and verifies the adapter receives the full conversation
  • Commit 2 applies the one-line fix, all tests pass
  • 93 existing tests unaffected

Summary by CodeRabbit

Bug Fixes

  • Resolved an issue where chat messages could be lost or become unavailable when the client is recreated. Message history is now properly maintained across all client updates, ensuring users always have access to their complete conversation history.

When setMessages and id change are batched into a single React render, the useEffect that updates messagesRef hasn't run yet. The new ChatClient is created with stale (empty) initialMessages, losing the conversation history. The test verifies that the adapter receives all previous messages when sending through the recreated client.
Replace useEffect ref update with synchronous render-time assignment so messagesRef is always current when useMemo creates a new ChatClient.
@changeset-bot
Copy link

changeset-bot bot commented Mar 13, 2026

🦋 Changeset detected

Latest commit: c1176b2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@tanstack/ai-react Patch
@tanstack/ai-react-ui Patch
@tanstack/smoke-tests-e2e Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 72044add-10d4-4d1f-8760-201cd9519e54

📥 Commits

Reviewing files that changed from the base of the PR and between 570c9f6 and c1176b2.

📒 Files selected for processing (3)
  • .changeset/fix-use-chat-messages-ref-staleness.md
  • packages/typescript/ai-react/src/use-chat.ts
  • packages/typescript/ai-react/tests/use-chat.test.ts

📝 Walkthrough

Walkthrough

The changes fix a staleness issue in the useChat hook by updating messagesRef synchronously during render instead of asynchronously in useEffect. This ensures the reference is current when ChatClient is recreated, with accompanying test coverage validating the behavior during client recreation with batched updates.

Changes

Cohort / File(s) Summary
Documentation
.changeset/fix-use-chat-messages-ref-staleness.md
New changeset entry documenting patch release for @tanstack/ai-react with behavioral change note about synchronous messagesRef updates during render.
Hook Implementation
packages/typescript/ai-react/src/use-chat.ts
Replaced effect-based messagesRef synchronization with render-time assignment, ensuring the reference is current before useMemo execution and preventing staleness on client recreation.
Test Coverage
packages/typescript/ai-react/tests/use-chat.test.ts
Added "client recreation" test block validating that messages persist and propagate correctly when client ID changes during batched state updates.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A ref that dances in the render,
No longer hiding in effects so tender,
When clients swap, the messages stay true,
Synchronous hops make old become new!
Fresh as a carrot, no staleness in sight, 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and concisely describes the main change: updating messagesRef synchronously during render, which is the core fix addressing the staleness issue.
Description check ✅ Passed The pull request description comprehensively covers the problem, solution, and test plan, but the PR description template sections (🎯 Changes, ✅ Checklist, 🚀 Release Impact) are not explicitly followed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Mar 13, 2026

View your CI Pipeline Execution ↗ for commit c1176b2

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 1m 6s View ↗
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 47s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-13 08:57:38 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 13, 2026

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@373

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@373

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@373

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@373

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@373

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@373

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@373

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@373

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@373

@tanstack/ai-groq

npm i https://pkg.pr.new/@tanstack/ai-groq@373

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@373

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@373

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@373

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@373

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@373

@tanstack/ai-react-ui

npm i https://pkg.pr.new/@tanstack/ai-react-ui@373

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@373

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/@tanstack/ai-solid-ui@373

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@373

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@373

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/@tanstack/ai-vue-ui@373

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@373

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@373

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@373

commit: 4eff0ac

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant